package cn.wink.springcloud.controller;

import cn.hutool.core.thread.ThreadUtil;
import cn.wink.springcloud.service.PaymentService;
import cn.wink.springcloud.utils.Result;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author xw
 * @date 2020-05-17 0:24
 */
@Slf4j
@RestController
@RequestMapping("/payment")
@DefaultProperties(defaultFallback = "globalFallMethod")
public class PaymentHystrixController {

    @Autowired
    private PaymentService paymentService;

    @HystrixCommand
    @GetMapping("/get/{id}")
    public Result getById(@PathVariable("id") Long id) {
        // ThreadUtil.sleep(3000);
        String str = paymentService.selectByPrimaryKey(id);
        log.info("查询数据为：{},不超时！！", str);
        Map<String,Object> map = new HashMap<>();
        map.put("payment",str);
        map.put("timeOut","0");
        return Result.ok(map);
    }

    // @HystrixCommand 对方法降级（fallback） 降级方法需与原方法签名一致（方法参数、返回值） 服务提供者
    @HystrixCommand(fallbackMethod = "fallbackMethod",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")
    })
    @GetMapping("/get/timeOut/{id}")
    public Result getByIdTimeOut(@PathVariable("id") Long id) {
        //超时
        ThreadUtil.sleep(3000L);
        // int i = 10/0;
        Map<String,Object> map = new HashMap<>();
        map.put("timeOut","3s");
        return Result.ok(map);
    }

    private Result fallbackMethod(Long id) {
        return Result.ok("服务提供者：服务降级,无法正确响应，提前定义的错误信息或响应");
    }

    private Result globalFallMethod() {
        return Result.ok("全局返回，降级方法！");
    }


    //====服务熔断==============//
    @HystrixCommand(fallbackMethod = "fallbackCircuitBreaker",commandProperties = {
            // 是否开启断路器
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
            // 请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10"),
            // 时间窗口
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "10000"),
            // 失败率达到多少拉闸
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "60")
    })
    @GetMapping("/circuit/{id}")
    public Result paymentCircuitBreaker(@PathVariable("id") Long id){
        if (id < 0){
            throw new RuntimeException("ID小于0==="+id);
        }
        return Result.ok("ID:"+id);
    }

    private Result fallbackCircuitBreaker(Long id) {
        log.info("服务熔断：执行超时，调用服务熔断方法！id:"+id);
        return Result.ok("服务熔断：执行超时，调用服务熔断方法！id:"+id);
    }

}
